#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <hs/hs.h>

// 定义一个回调函数，当匹配时被调用
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx);

int main(int argc, char **argv)
{
    // 正则表达式、编号、编译标志数组
    const char *patterns[] = {"ab+", "cd{2,}", "ef{1,3}"};
    const unsigned int ids[] = {101, 102, 103};
    const unsigned int flags[] = {HS_FLAG_CASELESS,
                                  HS_FLAG_CASELESS,
                                  HS_FLAG_CASELESS};

    unsigned int num_patterns = sizeof(patterns) / sizeof(const char *);

    // 编译正则表达式
    hs_database_t *database = NULL;
    hs_error_t err;
    hs_compile_error_t *compile_err = NULL;

    // 注意需要指定HS_MODE_STREAM模式
    err = hs_compile_multi(patterns, flags, ids, num_patterns, HS_MODE_BLOCK,
            NULL, &database, &compile_err);
    if (err != HS_SUCCESS) {
        printf("hs_compile_multi ERR_CODE[%d]: Pattern[%u]:\"%s\""
                "with error:\"%s\"",
                err,
                ids[compile_err->expression],
                expr[compile_err->expression],
                compile_err->message);
        hs_free_compile_error(compile_err);
        return -1;
    }

    // 分配临时空间(指针必须初始化为NULL)
    hs_scratch_t *scratch = NULL;
    err = hs_alloc_scratch(database, &scratch);
    if (err != HS_SUCCESS) {
        fprintf(stderr, "Error allocating scratch space\n");
        hs_free_database(database);
        return 1;
    }

    // 单模+块扫描
    const char *input = "abbcddefdefffabefffff";
    printf("Input: %s\n", input);
    err = hs_scan(database, input, strlen(input), 0, scratch,
                  on_match, patterns);
    if (err != HS_SUCCESS) {
        fprintf(stderr, "Error scanning input\n");
        hs_free_scratch(scratch);
        hs_free_database(database);
        return 1;
    }

    // 释放空间
    hs_free_scratch(scratch);
    hs_free_database(database);

    return 0;
}

// 定义一个回调函数，当匹配时被调用
static int on_match(unsigned int id, unsigned long long from,
        unsigned long long to, unsigned int flags, void *ctx)
{
    char **tmp = (char**)ctx;

    printf("Match found at end offset %llu with %s\n", to, tmp[id - 101]);

    return 0;
}
